/**
 * @package Infinity-Seed
 * @subpackage view
 *
 * @copyright Copyright (C) 2012-2013 Exia.CESI
 * @author Paul MAGNIN, Arthur MERCIER, Jordan RICHET, Cyril SCHUMACHER
 */
package view;

import Analyse.CellAnalyse;
import java.awt.*;
import java.awt.event.*;
import java.text.NumberFormat;
import java.util.logging.*;
import javax.swing.*;
import javax.swing.plaf.metal.MetalLookAndFeel;


/**
 * Fenêtre contenant le simulateur.
 * @author Cyril SCHUMACHER <cyril.schumacher at viacesi.fr>
 * @author Arthur MERCIER <arthur.mercier at viacesi.fr>
 * @author Jordan RICHET <jordan.richet at viacesi.fr>
 */
public class SimulatorWindow {
    // <editor-fold defaultstate="collapsed" desc="Attributs.">
    /**
     * Fenêtre.
     */
    private JFrame _frame;
    /**
     * Groupe d'ajout d'élément.
     */
    protected ButtonGroup radioGroup;
    /**
     * Position de la fenêtre de simulation.
     */
    private Point point = new Point();
    /**
     * Configuration.
     */
    private infinity.seed.Configuration _configuration;
    /**
     * Gestion de la simulation.
     */
    private CellAnalyse _simulation;
    /**
     *  Tableau modifié qui permet d'afficher la grille
     */
    protected int[][] array;
    /**
     *  Tableau de la même taille que la grille qui récupère le nouvel état de chaque cellule
     */
    protected int[][] transiArray;
    /**
     * Fenêtre contenant la grille.
     */
    private GridWindow _gridWindow;
    /**
     * Fenêtre contenant la grille.
     */
    private ActionWindow _actionWindow;
    /**
     * Fenêtre contenant la légende.
     */
    private LegendsWindow _legendsWindow;
    /**
     * Fenêtre contenant les statistiques.
     */
    private StatsWindow _statsWindow;
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Méthodes.">
    // <editor-fold defaultstate="collapsed" desc="Constructeur.">
    /**
     * Constructeur. Ce constructeur est utilise lorsque la grille doit etre creee.
     * @param sizeGrid Taille de la grille.
     */
    public SimulatorWindow(Dimension sizeGrid) {
        // Appelle le deuxieme constructeur en lui fournissant une grille initialisee.
        this(new int[sizeGrid.width][sizeGrid.height], sizeGrid);
    }
    
    /**
     * Constructeur. Ce constructeur est utilise lorsque la grille existe deja.
     * @param grid Grille.
     * @param sizeGrid Taille de la grille.
     * @param numberStep Nombre de pas.
     * @param numberTime  Temps entre chaque pas.
     */
    public SimulatorWindow(int[][] grid, Dimension sizeGrid) {
        try {
            // Adopte le thème Metal.
            UIManager.setLookAndFeel(new MetalLookAndFeel());
        } catch (UnsupportedLookAndFeelException ex) {
            Logger.getLogger(SimulatorWindow.class.getName()).log(Level.SEVERE, null, ex);
            JOptionPane.showMessageDialog(this._frame.getRootPane(), ex.getMessage(), "Erreur !", JOptionPane.ERROR);
            System.exit(1);
        }
        
        // Récupère une instance de la classe Configuration.
        this._configuration = infinity.seed.Configuration.getInstance();
        // Créer la fenêtre.
        this._frame = new JFrame(this._configuration.get("simulator.title"));
        
        this._simulation = new CellAnalyse();
        
        // Fenêtre contenant la légende.
        this._legendsWindow = new LegendsWindow();
        // Fenêtre contenant les interactions.
        this._actionWindow = new ActionWindow(this);
        // Fenêtre contenant les grilles.
        this._gridWindow = new GridWindow(grid, this);
        // Fenêtre contenant les statistiques.
        this._statsWindow = new StatsWindow(this, this._gridWindow);
        
        // Lie les fenêtres entre elles.
        this._actionWindow.setStatsWindow(_statsWindow);
        this._actionWindow.setGridWindow(_gridWindow);
        this._gridWindow.setActionWindow(_actionWindow);
        this._gridWindow.setStatsWindow(this._statsWindow);
        
        // Créer une instance de la classe CellAnalyse.
        this._simulation = new CellAnalyse();
        this.array = _gridWindow.grid;
        this.transiArray = new int[_gridWindow.grid.length][_gridWindow.grid[0].length];
        
        // Définit une icône.
        this._frame.setIconImage(new ImageIcon(getClass().getResource("/resources/SmallLogo.jpg")).getImage());
        // Définit l'action par défaut lorsque l'utilisateur clique sur le bouton Fermer.
        this._frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        // Initialise les composants.
        this._InitializeComponent();
        
        // Définit une couleur de fond et supprime la bordure.
        this._frame.setBackground(Color.decode(_configuration.get("jwindow.background")));
        this._frame.setUndecorated(true);
        
        // Redimensionne, positionne et affiche la fenêtre.
        this._frame.pack();
        this._frame.setLocation(20, 20);
        this._frame.setVisible(true);
        this._frame.setSize(475,280);
    }
    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Initialise les composants.">
    /**
     * Initialise les composants.
     */
    private void _InitializeComponent() {
        // <editor-fold defaultstate="collapsed" desc="Initialisation.">
        // Utilisation de police personnalisée.
        infinity.seed.CustomFont customFont = new infinity.seed.CustomFont();
        
        // Lie les événements à la fenêtre.
        SimulatorWindowEvent windowEvent = new SimulatorWindowEvent();
        this._frame.addMouseListener(windowEvent);
        this._frame.addMouseMotionListener(windowEvent);
        this._frame.addWindowStateListener(windowEvent);

        // Ajoute une disposition au contenu principale.
        BorderLayout contentPaneLayout = new BorderLayout();
        this._frame.getContentPane().setLayout(contentPaneLayout);
        this._frame.getRootPane().setBorder(BorderFactory.createLineBorder(Color.black));
        // </editor-fold> 
        // <editor-fold defaultstate="collapsed" desc="Barre de titre.">
        JPanel titlePanel = new JPanel();
        this._frame.getContentPane().add(titlePanel, BorderLayout.PAGE_START);
        titlePanel.setLayout(new GridLayout(0,2));
        
        JPanel titleLeftPanel = new JPanel();
        titleLeftPanel.setBackground(Color.decode(_configuration.get("jwindow.background")));
        titleLeftPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
        titlePanel.add(titleLeftPanel);
        
        // Bouton "Regrouper".
        JButton aggregateButton = new JButton("Ξ");
        titleLeftPanel.add(aggregateButton);
        aggregateButton.setToolTipText(this._configuration.get("aggregateButton.text"));
        aggregateButton.setBackground(titleLeftPanel.getBackground());
        aggregateButton.setOpaque(true);
        aggregateButton.setForeground(Color.WHITE);
        aggregateButton.setFont(new Font(aggregateButton.getFont().getFontName(), aggregateButton.getFont().getStyle(), 15));
        aggregateButton.setBorder(BorderFactory.createMatteBorder(0, 2, 0, 2, aggregateButton.getBackground()));
        aggregateButton.addActionListener(new ActionListener() {
            @Override public void actionPerformed(ActionEvent e) {
                _actionWindow.frame.setLocation(425,305);
                _actionWindow.frame.toFront();
                _gridWindow.frame.setLocation(660, 20);
                _gridWindow.frame.toFront();
                _legendsWindow.frame.setLocation(425,385);
                _legendsWindow.frame.toFront();
                _statsWindow.frame.setLocation(20,305);
                _statsWindow.frame.toFront();
                _frame.setLocation(20, 20);
                _frame.toFront();
                
            }
        });

        JPanel titleRightPanel = new JPanel();
        titleRightPanel.setBackground(Color.decode(_configuration.get("jwindow.background")));
        titleRightPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
        titlePanel.add(titleRightPanel);
        
        // Bouton "Reduire".
        JButton minimizerButton = new JButton("_");
        titleRightPanel.add(minimizerButton);
        minimizerButton.setToolTipText(this._configuration.get("jwindow.minimize.text"));
        minimizerButton.setBackground(titleRightPanel.getBackground());
        minimizerButton.setOpaque(true);
        minimizerButton.setForeground(Color.WHITE);
        minimizerButton.setFont(new Font(minimizerButton.getFont().getFontName(), minimizerButton.getFont().getStyle(), 15));
        minimizerButton.setBorder(BorderFactory.createEmptyBorder(2,7,2,7));
        // <editor-fold defaultstate="collapsed" desc="Evenements pour le composant "minimizerButton".">
        minimizerButton.addMouseListener(new MouseAdapter() {
            /**
             * Lorsque le curseur est sur l'élément.
             */
            @Override public void mouseEntered(MouseEvent e) {
                ((JComponent)e.getSource()).setBackground(Color.decode(_configuration.get("jwindow.minimize.background")));
            }
            /**
             * Lorsque le curseur quitte l'élément.
             */
            @Override public void mouseExited(MouseEvent e) {
                ((JComponent)e.getSource()).setBackground(Color.decode(_configuration.get("jwindow.background")));
            }
        });
        minimizerButton.addActionListener(new ActionListener() {
            /**
             * Ferme la fenetre lorsque le client clique sur ce bouton.
             */
            @Override public void actionPerformed(ActionEvent e) {
                _frame.setState(JFrame.ICONIFIED);
            }
        });
        // </editor-fold>

        // Bouton "Fermer".
        JButton closeButton = new JButton("x");
        titleRightPanel.add(closeButton);
        closeButton.setToolTipText(this._configuration.get("jwindow.close.text"));
        closeButton.setBackground(titleRightPanel.getBackground());
        closeButton.setOpaque(true);
        closeButton.setForeground(Color.WHITE);
        closeButton.setFont(new Font(closeButton.getFont().getFontName(), closeButton.getFont().getStyle(), 15));
        closeButton.setBorder(BorderFactory.createEmptyBorder(2,7,2,7));
        // <editor-fold defaultstate="collapsed" desc="Evenements pour le composant "closeButton".">
        closeButton.addMouseListener(new MouseAdapter() {
            /**
             * Lorsque le curseur est sur l'élément.
             */
            @Override public void mouseEntered(MouseEvent e) {
                ((JComponent)e.getSource()).setBackground(Color.decode(_configuration.get("jwindow.close.background")));
            }
            /**
             * Lorsque le curseur quitte l'élément.
             */
            @Override public void mouseExited(MouseEvent e) {
                ((JComponent)e.getSource()).setBackground(Color.decode(_configuration.get("jwindow.background")));
            }
        });
        closeButton.addActionListener(new ActionListener() {
            @Override public void actionPerformed(ActionEvent e) {
                // Demande au client si il est sûr de vouloir fermer l'application.
                int confirm = JOptionPane.showConfirmDialog(_frame, _configuration.get("simulator.confirm.text"), _configuration.get("application.title"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
                if (confirm == JOptionPane.YES_OPTION) {
                    // Ferme l'application.
                    System.exit(0);
                }
            }
        });
        // </editor-fold>
        // </editor-fold>
        // <editor-fold defaultstate="collapsed" desc="Contenu de la fenêtre.">
        JPanel contentPanel = new JPanel();
        contentPanel.setLayout(new BorderLayout());
        this._frame.getContentPane().add(contentPanel);
        
        // <editor-fold defaultstate="collapsed" desc="Type de cellule à ajouter">
        JPanel addCellPanel = new JPanel();
        BoxLayout addCellLayout = new BoxLayout(addCellPanel, BoxLayout.Y_AXIS);
        addCellPanel.setLayout(addCellLayout);
        addCellPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        contentPanel.add(addCellPanel, BorderLayout.WEST);

        JLabel addCellLabel = new JLabel(this._configuration.get("addCellLabel.text"));
        addCellLabel.setFont(customFont.getFont("/resources/open-sans/OpenSans-Semibold.ttf", 24));
        addCellPanel.add(addCellLabel);

        this.radioGroup = new ButtonGroup();
        JRadioButton emptyRadioButton = new JRadioButton(this._configuration.get("emptyRadioButton.text"), true);
        emptyRadioButton.setActionCommand("empty");
        emptyRadioButton.setFont(customFont.getFont("/resources/open-sans/OpenSans-Regular.ttf", 12));
        addCellPanel.add(emptyRadioButton);
        this.radioGroup.add(emptyRadioButton);

        JRadioButton seedRadioButton = new JRadioButton(this._configuration.get("seedRadioButton.text"));
        seedRadioButton.setActionCommand("seed");
        seedRadioButton.setFont(customFont.getFont("/resources/open-sans/OpenSans-Regular.ttf", 12));
        addCellPanel.add(seedRadioButton);
        this.radioGroup.add(seedRadioButton);

        JRadioButton bushRadioButton = new JRadioButton(this._configuration.get("bushRadioButton.text"));
        bushRadioButton.setActionCommand("bush");
        bushRadioButton.setFont(customFont.getFont("/resources/open-sans/OpenSans-Regular.ttf", 12));
        addCellPanel.add(bushRadioButton);
        this.radioGroup.add(bushRadioButton);

        JRadioButton treeRadioButton = new JRadioButton(this._configuration.get("treeRadioButton.text"));
        treeRadioButton.setActionCommand("tree");
        treeRadioButton.setFont(customFont.getFont("/resources/open-sans/OpenSans-Regular.ttf", 12));
        addCellPanel.add(treeRadioButton);
        this.radioGroup.add(treeRadioButton);

        JRadioButton infiredRadioButton = new JRadioButton(this._configuration.get("infiredRadioButton.text"));
        infiredRadioButton.setActionCommand("infired");
        infiredRadioButton.setFont(customFont.getFont("/resources/open-sans/OpenSans-Regular.ttf", 12));
        addCellPanel.add(infiredRadioButton);
        this.radioGroup.add(infiredRadioButton);

        JRadioButton infectedRadioButton = new JRadioButton(this._configuration.get("infectedRadioButton.text"));
        infectedRadioButton.setActionCommand("infected");
        infectedRadioButton.setFont(customFont.getFont("/resources/open-sans/OpenSans-Regular.ttf", 12));
        addCellPanel.add(infectedRadioButton);
        this.radioGroup.add(infectedRadioButton);
        // </editor-fold>
        // <editor-fold defaultstate="collapsed" desc="Options.">
        JPanel optionsPanel = new JPanel();
        BoxLayout optionsLayout = new BoxLayout(optionsPanel, BoxLayout.Y_AXIS);
        optionsPanel.setLayout(optionsLayout);
        optionsPanel.setBorder(BorderFactory.createEmptyBorder(5, 10, 10, 10));
        contentPanel.add(optionsPanel, BorderLayout.EAST);
        
        JPanel optionLabelPanel = new JPanel();
        optionLabelPanel.setMaximumSize(new Dimension(200,40));
        optionLabelPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
        optionsPanel.add(optionLabelPanel);
        
        JLabel optionLabel = new JLabel(this._configuration.get("optionLabel.text"));
        optionLabel.setFont(customFont.getFont("/resources/open-sans/OpenSans-Semibold.ttf", 24));
        optionLabelPanel.add(optionLabel);
        
        // Format du champs : uniquement 3 chiffres. 
        NumberFormat onlyNumberField = NumberFormat.getNumberInstance();
        onlyNumberField.setMaximumIntegerDigits(3);
        
        // Conteneur  qui contiendra le champs de texte (evite que le composant prennent la taille de la cellule).
        JPanel timerPanel = new JPanel();
        timerPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
        timerPanel.setMaximumSize(new Dimension(200,30));
        optionsPanel.add(timerPanel);
        
        // Label.
        JLabel timerLabel = new JLabel(this._configuration.get("timerLabel.text"));
        timerLabel.setFont(customFont.getFont("/resources/open-sans/OpenSans-Regular.ttf", 12));
        timerPanel.add(timerLabel);

        // Nombre de pas.
        JFormattedTextField numberStepButton = new JFormattedTextField(onlyNumberField);
        numberStepButton.setName("numberStep");
        numberStepButton.setText(_configuration.get("grid.step"));
        numberStepButton.setPreferredSize(new Dimension(40, 20));
        numberStepButton.setBackground(Color.decode(_configuration.get("jtextfield.background")));
        numberStepButton.setBorder(BorderFactory.createLineBorder(Color.decode(_configuration.get("jtextfield.border"))));
        numberStepButton.setBorder(BorderFactory.createLineBorder(Color.black));
        numberStepButton.addFocusListener(new NumberStepButtonEvents());
        timerPanel.add(numberStepButton);

        // Conteneur  qui contiendra le champs de texte (evite que le composant prennent la taille de la cellule).
        JPanel timeStepPanel = new JPanel();
        timeStepPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
        timeStepPanel.setMaximumSize(new Dimension(300,40));
        optionsPanel.add(timeStepPanel);
        
        JLabel timeStepLabel = new JLabel(this._configuration.get("timeStepLabel.text"));
        timeStepLabel.setFont(customFont.getFont("/resources/open-sans/OpenSans-Regular.ttf", 12));
        timeStepPanel.add(timeStepLabel);

        // Temps entre chaque pas.
        JFormattedTextField timeStepButton = new JFormattedTextField(onlyNumberField);
        timeStepButton.setName("timeStep");
        timeStepButton.setText(_configuration.get("grid.time"));
        timeStepButton.setPreferredSize(new Dimension(40, 20));
        timeStepButton.setBackground(Color.decode(_configuration.get("jtextfield.background")));
        timeStepButton.setBorder(BorderFactory.createLineBorder(Color.decode(_configuration.get("jtextfield.border"))));
        timeStepButton.setBorder(BorderFactory.createLineBorder(Color.black));
        timeStepButton.addFocusListener(new NumberStepButtonEvents());
        timeStepPanel.add(timeStepButton);

        // Label.
        /*JLabel secondsLabel = new JLabel(" secondes");
        secondsLabel.setFont(customFont.getFont("/resources/open-sans/OpenSans-Regular.ttf", 12));
        timeStepPanel.add(secondsLabel);*/
        
        JPanel updatePanel = new JPanel();
        updatePanel.setLayout(new FlowLayout(FlowLayout.LEFT));
        optionsPanel.add(updatePanel);
        // </editor-fold>
        // <editor-fold defaultstate="collapsed" desc="Bouton.">
        JPanel navigatePanel = new JPanel();
        navigatePanel.setLayout(new FlowLayout(FlowLayout.CENTER));
        contentPanel.add(navigatePanel, BorderLayout.PAGE_END);
        
        // Bouton "Sauvegarder".
        JButton saveButton = new JButton(this._configuration.get("saveButton.text").toUpperCase());
        try {
            save.SaveGrid save = new save.SaveGrid();
            save.setBehaviour(new save.format.SaveDatabase());
        }
        catch(Exception e) {
            saveButton.setEnabled(false);
        }
        
        saveButton.setToolTipText(this._configuration.get("saveButton.tooltip"));
        saveButton.setFont(customFont.getFont("/resources/open-sans/OpenSans-Bold.ttf", 15));
        saveButton.setBackground(Color.decode(_configuration.get("jbutton.background")));
        saveButton.setForeground(Color.decode(_configuration.get("jbutton.text")));
        saveButton.setBorder(BorderFactory.createEmptyBorder(5, 25, 5, 25));
        saveButton.addMouseListener(new ButtonEvent());
        saveButton.addMouseListener(new SaveButtonEvents());
        navigatePanel.add(saveButton);
        
        optionsPanel.add(Box.createRigidArea(new Dimension(0, 5)));

        // Bouton "Retourner au menu".
        JButton returnMenuButton = new JButton(this._configuration.get("returnMenuButton.text").toUpperCase());
        returnMenuButton.setToolTipText(this._configuration.get("returnMenuButton.tooltip"));
        returnMenuButton.setFont(customFont.getFont("/resources/open-sans/OpenSans-Bold.ttf", 15));
        returnMenuButton.setBackground(Color.decode(_configuration.get("jbutton.background")));
        returnMenuButton.setForeground(Color.decode(_configuration.get("jbutton.text")));
        returnMenuButton.setBorder(BorderFactory.createEmptyBorder(5, 25, 5, 25));
        returnMenuButton.addMouseListener(new ButtonEvent());
        returnMenuButton.addMouseListener(new ReturnButtonEvents());
        navigatePanel.add(returnMenuButton);
        // </editor-fold>
        // </editor-fold>
    }
    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Simule la forêt.">
    /**
     * Simule la forêt.
     * @return Retourne la nouvelle grille.
     */
    protected int[][] simulate() {
        this._simulation.setTransiArray(transiArray);
        this._simulation.setArray(array);

        // Définit la dimension de la grille.
        this._simulation.setX_size(_gridWindow.grid.length);
        this._simulation.setY_size(_gridWindow.grid[0].length);
        try {
            // Commence la simulation.
            _simulation.startSimulation();
            _simulation.getNewArray(array, transiArray, _gridWindow.grid.length, _gridWindow.grid[0].length);

        } catch (InterruptedException ex) {
            Logger.getLogger(SimulatorWindow.class.getName()).log(Level.SEVERE, null, ex);
        }

        // Recupere le nombre des elements contenus dans la grille.
        this._statsWindow.updateStats();
        return _simulation.getArray();
    }
    // </editor-fold>
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Evénements.">
    // <editor-fold defaultstate="collapsed" desc="Gestion des événements pour la fenêtre.">
    /**
     * Evènements de la fenêtre.
     * @see <a href="http://docs.oracle.com/javase/7/docs/api/java/awt/event/MouseAdapter.html">MouseAdapter</a>
     * @see <a href="http://docs.oracle.com/javase/7/docs/api/java/awt/event/WindowStateListener.html">WindowStateListener</a>
     */
    private class SimulatorWindowEvent extends MouseAdapter implements WindowStateListener {

        /**
         * Recupere la position du curseur.
         * @param e Parametres.
         */
        @Override public void mousePressed(MouseEvent e) {
            point.x = e.getX();
            point.y = e.getY();
        }

        /**
         * Selon la position du curseur, on déplace la fenêtre.
         * @param e Paramètres.
         */
        @Override
        public void mouseDragged(MouseEvent e) {
            JFrame frame = (JFrame) e.getSource();
            Point position = frame.getLocation();
            frame.setLocation(position.x + e.getX() - point.x, position.y + e.getY() - point.y);
        }
        
        /**
         * Changement d'état de la fenêtre.
         * @param e Paramètres.
         */
        @Override public void windowStateChanged(WindowEvent e) {
            // Vue normale et réduit.
            if (_frame.getState() == JFrame.NORMAL) {
                _actionWindow.frame.setVisible(true);
                _gridWindow.frame.setVisible(true);
                _legendsWindow.frame.setVisible(true);
                _statsWindow.frame.setVisible(true);
            } else if(_frame.getState() == JFrame.ICONIFIED) {
                _actionWindow.frame.setVisible(false);
                _gridWindow.frame.setVisible(false);
                _legendsWindow.frame.setVisible(false);
                _statsWindow.frame.setVisible(false);
            }
        }
    }
    // </editor-fold>  
    // <editor-fold defaultstate="collapsed" desc="Gestion des événements pour le bouton "Sauvegarde de la grille".">
    /**
     * Gestion des evenements pour le bouton "Sauvegarde de la grille".
     */
    private class SaveButtonEvents extends MouseAdapter {
        @Override public void mouseClicked(MouseEvent e) {
            save.SaveGrid save = new save.SaveGrid();
            save.setBehaviour(new save.format.SaveDatabase());

            // Sauvegarde la grille, le nombre de pas et le temps entre chaque pas dans la base de donnÃ©es.
            Boolean isSave = save.setGrid(new Dimension(_gridWindow.grid.length, _gridWindow.grid[0].length), 0, 0, _gridWindow.grid);
            String messageSave = "Une erreur est survenue lors de la sauvegarde.";
            int iconMessageDialog = JOptionPane.ERROR_MESSAGE;
            if(isSave.equals(true)) {
                iconMessageDialog = JOptionPane.PLAIN_MESSAGE;
                messageSave = "Votre sauvegarde a bien été effectué.";
            }

            JOptionPane.showMessageDialog(_frame, messageSave, "Sauvegarde", iconMessageDialog);
        }
    }
    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Gestion des évènements pour le bouton "Retourner au menu".">
    /**
     * Gestion des évènements pour le bouton "Retourner au menu".
     */
    private class ReturnButtonEvents extends MouseAdapter {
        @Override public void mouseClicked(MouseEvent e) {
            // Ferme toutes les fenêtres ouvertes.
            _frame.dispose();
            _gridWindow.frame.dispose();
            _legendsWindow.frame.dispose();
            _actionWindow.frame.dispose();
            _statsWindow.frame.dispose();
            
            // Détruit les instances.
            _frame = null;
            _gridWindow = null; 
            _legendsWindow = null;
            _actionWindow = null;
            _statsWindow = null;
            
            // Affiche le menu.
            MenuWindow menuWindow = new MenuWindow();
        }
    }
    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Gestion des événements pour le bouton "Changement de valeur".">
    /**
     * Gestion des événements pour le bouton "Changement de valeur".
     */
    private class NumberStepButtonEvents extends FocusAdapter {
        /**
         * Lorsque l'élément perd le focus.
         * @param e Paramètres.
         */
        @Override public void focusLost(FocusEvent e) {
            JFormattedTextField textField = (JFormattedTextField)e.getSource();
            try {
                int value = Integer.parseInt(textField.getText());
                switch (textField.getName()) {
                    case "numberStep":
                        _statsWindow.setStepNumber(value);
                        break;
                    case "timeStep":
                        _statsWindow.setTimeNumber(value);
                        break;

                }
            } catch(NumberFormatException ex) {
            }
        }
    }
    // </editor-fold>
    // </editor-fold>
}